home *** CD-ROM | disk | FTP | other *** search
- # -*- Mode: Python; tab-width: 4 -*-
-
- import regex
- import string
- import time
-
- def concat (*args):
- return string.joinfields (args, '')
-
- def join (seq, field=' '):
- return string.joinfields (seq, field)
-
- def group (s):
- return '\\(' + s + '\\)'
-
- short_days = ['sun','mon','tue','wed','thu','fri','sat']
- long_days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
-
- short_day_reg = group (join (short_days, '\\|'))
- long_day_reg = group (join (long_days, '\\|'))
-
- daymap = {}
- for i in range(7):
- daymap[short_days[i]] = i
- daymap[long_days[i]] = i
-
- hms_reg = join (3 * [group('[0-9][0-9]')], ':')
-
- months = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']
-
- monmap = {}
- for i in range(12):
- monmap[months[i]] = i+1
-
- months_reg = group (join (months, '\\|'))
-
- # From draft-ietf-http-v11-spec-07.txt/3.3.1
- # Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
- # Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
- # Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
-
- # rfc822 format
- rfc822_date = join (
- [concat (short_day_reg,','), # day
- group('[0-9][0-9]?'), # date
- months_reg, # month
- group('[0-9]+'), # year
- hms_reg, # hour minute second
- 'gmt'
- ],
- ' '
- )
-
- rfc822_reg = regex.compile (rfc822_date)
-
- def unpack_rfc822 ():
- g = rfc822_reg.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
- # rfc850 format
- rfc850_date = join (
- [concat (long_day_reg,','),
- join (
- [group ('[0-9][0-9]?'),
- months_reg,
- group ('[0-9]+')
- ],
- '-'
- ),
- hms_reg,
- 'gmt'
- ],
- ' '
- )
-
- rfc850_reg = regex.compile (rfc850_date)
- # they actually unpack the same way
- def unpack_rfc850 ():
- g = rfc850_reg.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
- # parsdate.parsedate - ~700/sec.
- # parse_http_date - ~1333/sec.
-
- weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
- monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
- def build_http_date (when):
- year, month, day, hh, mm, ss, wd, y, z = time.gmtime(when)
- return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
- weekdayname[wd],
- day, monthname[month], year,
- hh, mm, ss)
-
- def parse_http_date (d):
- d = string.lower (d)
- tz = time.timezone
- if rfc850_reg.match (d) == len(d):
- retval = int (time.mktime (unpack_rfc850()) - tz)
- elif rfc822_reg.match (d) == len(d):
- retval = int (time.mktime (unpack_rfc822()) - tz)
- else:
- return 0
- # Thanks to Craig Silverstein <csilvers@google.com> for pointing
- # out the DST discrepancy
- if time.daylight and time.localtime(retval)[-1] == 1: # DST correction
- retval = retval + (tz - time.altzone)
- return retval
-